\documentclass[12pt]{article}
\usepackage[english]{babel}
\usepackage{natbib}
\usepackage{url}
\usepackage[utf8x]{inputenc}
\usepackage{amsmath}
\usepackage{graphicx}
\graphicspath{{images/}}
\usepackage{parskip}
\usepackage[space]{xeCJK}
\usepackage{fancyhdr}
\usepackage{vmargin}
\usepackage{listings}
\usepackage{xcolor}
\lstset{
    columns=fixed,       
    numbers=left,                                        % 在左侧显示行号
    frame=none,                                          % 不显示背景边框
    backgroundcolor=\color[RGB]{245,245,244},            % 设定背景颜色
    keywordstyle=\color[RGB]{40,40,255},                 % 设定关键字颜色
    numberstyle=\footnotesize\color{darkgray},           % 设定行号格式
    commentstyle=\it\color[RGB]{0,96,96},                % 设置代码注释的格式
    stringstyle=\rmfamily\slshape\color[RGB]{128,0,0},   % 设置字符串格式
    showstringspaces=false,                              % 不显示字符串中的空格
    language=python,                                     % 设置语言
}
\setmarginsrb{3 cm}{2.5 cm}{3 cm}{2.5 cm}{1 cm}{1.5 cm}{1 cm}{1.5 cm}


							


\makeatletter
\let\thetitle\@title

\let\thedate\@date
\makeatother

\pagestyle{fancy}
\fancyhf{}
\rhead{\theauthor}
\lhead{\thetitle}
\cfoot{\thepage}

\begin{document}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{titlepage}
	\centering
    \vspace*{0.5 cm}
    \includegraphics[scale = 0.5]{symbol.jpg}\\[1.0 cm]	% University Logo
    \textsc{\LARGE SOUTHEAST UNIVERSITY}\\[2.0 cm]
    \textsc{\lARGE 软件学院}\\[0.2 cm]
    \textsc{\lARGE 软件体系结构课程项目}\\[2.0 cm]
	%\textsc{\Large CSE 322}\\[0.5 cm]				% Course Code
	\textsc{\LARGE IBBB \quad 单 \quad 词 \quad 学 \quad 习 \quad 系 \quad 统}\\[0.2 cm]
	\rule{\linewidth}{0.2 mm} \\[0.4 cm]
	{ \huge \bfseries \thetitle}\\
	
	
	\begin{minipage}{0.4\textwidth}
		
			\begin{flushleft} 
			\emph{组员:} \\
			71Y18108\ 李渊\linebreak
			71Y18107\ 王宸\linebreak
			71118415\ 叶宏庭\linebreak
			71118312\ 谈金翰\linebreak
			71118313\ 张晓铮\linebreak
			71Y18109\ 芦小栋
		\end{flushleft}
	\end{minipage}\\[2 cm]
	

 
	\vfill
	
\end{titlepage}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\tableofcontents
\pagebreak

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{简介}
\subsection{项目背景}
  为了解决在英语单词学习中出现的以下问题：
   \par 1.不同需求的用户，需要有对应的词库练习
   \quad \\2.对于单词，需要掌握其具体用法
   \quad \\3.背单词的喜好，有顺序，乱序，按类别分类等偏好
   \quad \\4.背单词后出现模糊，遗忘
   \quad \\5.需要一个制定的计划，时间安排来完成任务计划 所以，开发外语单词学习系统。
   \par 故计划IBBB单词学习项目，以期最大化解决这些问题。

\section{需求}
\subsection{User Stories}
\subsubsection*{User}
1.User可以登录
\par 2.登录后，User可以选择切换对应的词库等级
\par 3.登录后，User可以制定计划学习，选择学习方式
\par 4.登录后，User可以对单词进行实题练习
\par 5.登录后，User可以看到自己的学习情况
\par 6.登录后,User 可以记录笔记并选择公布
\subsubsection*{Administrator}
1.管理员需要登录
\par 3.管理员可以增删改查词库
\par 4.管理员可以对用户进行管理


\subsection{非功能需求}
\par 1.性能：支持多人在线
\par 2.界面：简洁美观，操作简单，入口明显
\par 3.安全性：保护用户数据隐私，避免泄露
\par 4.可维护性：数据模块化，做到低耦合
\par 以下为质量需求表\\
\begin{tabular}{| l | p{12.5cm} |}%l(left)居左显示 r(right)居右显示 c居中显示
\hline 
目标&说明\\
\hline  
性能&用户访问的系统能在规定时间内做出响应，若因为系统网络原因不能及时响应，系统应该提出警告，防止出现用户长时间等待的情况。\\
\hline 
正确性&为了保证请求信息的正确性，用户服务器应对客户端的请求进行筛选验证，丢弃错误无效信息，对正确信息进行下一步处理。\\
\hline
易用性&不同的用户应该能够以不同形式访问不同的内容\\
\hline
安全性&将数据库和服务器分开，提高数据安全性。\\
\hline
可维护性&模块层次划分合理，便于后期因需求变化、环境变化、系统错误引起的系统维护工作。\\
\hline
可测试性&系统的各部分易于单独测试，并能方便地进行整体测试\\
\hline
\end{tabular}
\\质量需求\\[0.2cm]

\subsection{Use Cases}
1.用例图\\[0.3cm]
\includegraphics[scale = 0.4]{UseCase.png}
\par 2.用例规约\\[0.3cm]
\begin{tabular}{| l | p{12.5cm} |}%l(left)居左显示 r(right)居右显示 c居中显示
\hline 
Items&Descriptions\\
\hline  
用例名称&登录\\
\hline 
简要描述&用户及管理员均可使用的登录功能\\
\hline
基础流程&1. 选择用户登录或管理员登录
\par 2. 输入账号、密码
\par 3. 验证账号、密码 返回验证结果\\
\hline
可选流程&登录用户账号或管理员账号\\
\hline
前置条件&已注册过账号\\
\hline
后置条件&无\\
\hline
\end{tabular}
\\表1：登录规约\\[0.2cm]

\begin{tabular}{| l | p{12.5cm} |}%l(left)居左显示 r(right)居右显示 c居中显示
\hline 
Items&Descriptions\\
\hline  
用例名称&选择词库等级\\
\hline 
简要描述&用户可以根据自己的需求，选择不同的词库进行学习， 如：四六级、托福雅思\\
\hline
基础流程&1. 用户选择相关词库
\par 2. 用户将词库加入“我的词库”并下载\\
\hline
可选流程&未联网状态提醒无法操作\\
\hline
前置条件&用户已经登录\\
\hline
后置条件&可以针对词库进行学习计划的制定\\
\hline
\end{tabular}
\\表2：选择词库等级\\[0.2cm]

\begin{tabular}{| l | p{12.5cm} |}%l(left)居左显示 r(right)居右显示 c居中显示
\hline 
Items&Descriptions\\
\hline  
用例名称&单词复习\\
\hline 
简要描述&用户登陆系统后可以根据自己制定的学习计划和已有的学习进度进行单词的复习\\
\hline
基础流程&1. 进入复习界面   
\par 2.系统检测用户的学习进度
\par 3.系统从用户最近所学单词中随机地抽取部分单词呈现
\par 4.用户选择单词的用法及意义
\par 5.用户查看复习结果\\
\hline
可选流程&未联网，调用本地数据包\\
\hline
前置条件&1. 用户已登录
\par 2.用户最近有过学习计划并学习过一定量的单词\\
\hline
后置条件&无\\
\hline
\end{tabular}
\\表3：单词复习\\[0.2cm]

\begin{tabular}{| l | p{12.5cm} |}%l(left)居左显示 r(right)居右显示 c居中显示
\hline 
Items&Descriptions\\
\hline  
用例名称&新单词学习\\
\hline 
简要描述&用户登陆并设置学习计划后可以学习新的单词\\
\hline
基础流程&1. 用户登陆  
\par 2.根据已选词库和已制定计划学习新的单词
\par 3.系统记录用户的学习进度\\
\hline
可选流程&没有联网，无法进行学习提示异常\\
\hline
前置条件&1. 用户已登录
\par 2.用户已经选择单词包
\par 3.用户已经制定学习计划\\
\hline
后置条件&1.更新复习计划
\par 2.用户可以添加笔记 \\
\hline
\end{tabular}
\\表4：新单词学习\\[0.2cm]


\begin{tabular}{| l | p{12.5cm} |}%l(left)居左显示 r(right)居右显示 c居中显示
\hline 
Items&Descriptions\\
\hline  
用例名称&查看学习情况\\
\hline 
简要描述&用户可以查看自己已有的学习情况，包括所学词库单词数量，以及进度\\
\hline
基础流程&1. 用户进入学习情况统计界面        
\par 2. 系统显示用户学习情况，包括已学单词数量、每日学习词数和学习进度\\
\hline
可选流程&网络异常时，显示之前保存的进度\\
\hline
前置条件&1. 用户已登录
\par 2.用户已经选择单词包\\
\hline
后置条件&无\\
\hline
\end{tabular}
\\表5：查看学习情况\\[0.2cm]


\begin{tabular}{| l | p{12.5cm} |}%l(left)居左显示 r(right)居右显示 c居中显示
\hline 
Items&Descriptions\\
\hline  
用例名称&导出笔记本\\
\hline 
简要描述&用户可以将自己学习过程中的笔记导出\\
\hline
基础流程&1.用户进入学习单词的界面陆       
\par 2.选择笔记进行编辑
\par 3. 导出笔记至word\\
\hline
可选流程&网络异常时，从本地数据导出笔记本\\
\hline
前置条件&1.用户已经登录
\par 2. 用户编辑过笔记\\
\hline
后置条件&用户可将导出的笔记分享\\
\hline
\end{tabular}
\\表6：导出笔记本\\[0.2cm]


\begin{tabular}{| l | p{12.5cm} |}%l(left)居左显示 r(right)居右显示 c居中显示
\hline 
Items&Descriptions\\
\hline  
用例名称&管理词库\\
\hline 
简要描述&管理对词库进行更新操作(包括增、删、改)\\
\hline
基础流程&1. 管理员选定某个词库       
\par 2.对选定词库进行更新操作\\
\hline
可选流程&可以对多个词库进行批量操作\\
\hline
前置条件&管理员账号已经登录\\
\hline
后置条件&服务器端向用户推送最新词库\\
\hline
\end{tabular}
\\表7：管理词库\\[0.2cm]


\begin{tabular}{| l | p{12.5cm} |}%l(left)居左显示 r(right)居右显示 c居中显示
\hline 
Items&Descriptions\\
\hline  
用例名称&用户管理\\
\hline 
简要描述&管理员对用户的账号信息进行管理\\
\hline
基础流程&对用户进行信息管理，包括账号、密码、个人信息等\\
\hline
可选流程&无\\
\hline
前置条件&1.管理员账号已经登录
\par 2.用户要求修改信息\\
\hline
后置条件&无\\
\hline
\end{tabular}
\\表8：用户管理\\[0.2cm]

\subsection{活动图}
\includegraphics[scale = 0.4]{登录活动图.png}\\登录活动图\\[0.2cm]
\includegraphics[scale = 0.4]{选择词库等级活动图.png}\\选择词库等级活动图\\[0.2cm]
\includegraphics[scale = 0.4]{单词复习活动图.png}\\单词复习活动图\\[0.2cm]
\includegraphics[scale = 0.4]{新单词学习活动图.png}\\新单词学习活动图\\[0.2cm]
\includegraphics[scale = 0.4]{6.png}\\查看学习情况活动图\\[0.2cm]
\includegraphics[scale = 0.4]{7.png}\\导出笔记本活动图\\[0.2cm]
\includegraphics[scale = 0.4]{8.png}\\管理词库活动图\\[0.2cm]
\includegraphics[scale = 0.4]{11.png}\\用户管理活动图\\[0.2cm]

\section{IBBB单词学习系统架构}
\subsection{总体功能设计}
\includegraphics[scale = 0.4]{系统架构图.png}
1. IBBB单词学习系统采用三层CS的架构风格，总体上分为用户层，应用服务层（Server层），数据 库层。
\par 2. 其中用户层分为根据类型分为普通用户模块，和管理员模块。
\par \quad \quad 普通用户模块下，包括登录，单词学习，查看个人信息，管理笔记本功能
\par \quad \quad 管理员模块下，包括登陆系统，用户管理，更新词库题库等功能
\par 3. 应用服务器层（Server层）根据信息划分为接收、处理模块。
\par \quad \quad 信息接收模块只要负责接收信息，创建相应的响应线程
\par \quad \quad 信息处理模块则负责信息识别，信息反馈，以及对数据库的调用
\par 4. 数据库层接收server的发送的消息，执行信息识别，数据库查询，并最终返回结果。
\subsection{体系结构设计}
\subsubsection*{总体架构}
\includegraphics[scale = 0.5]{总体架构.png}
\par 主要将系统分为表示层，处理层和数据库层三层。表示层展示fxml定义的组件，用户通过点击按钮发送请求，处理层中对应的表示层组件的Controller判断按钮请求并调用通信模块来向服务器传递参数请求服务，服务器监听到服务后判断请求的是什么服务并交给对应的处理程序处理程序调用数据库的接口获取数据，再将获取到的信息返回。Controller获取返回的信息后，利用信息更新相应的model，model由于和表示层的fxml进行了绑定，从而完成信息展示的更新
\subsubsection*{详细架构}
\includegraphics[scale = 0.5]{详细架构.png}
\par IBBB单词系统采用经典的三层C/S架构，将软件系统分为应用层、服务层及数据层，使得系统具有逻辑结构清晰，易于维护的优点。\par
应用层：\\
职责是与用户进行交互，并向服务层发送数据请求，接收需要的数据，以完成用户的需求。
应用层主要分为用户界面和功能实现两大板块。通过对JavaFX的应用实现了用户的交互界面与软件的功能实现、数据交换的解耦。并在大的板块内细分出数据请求与接收、背单词、单词复习、计划、选词库、个人信息等模块，降低了系统功能之间的相互依赖，大大减少了维护与添加新功能的成本。应用层与服务层之间通过socket进行数据的请求和接收。\par
服务器层：\\
服务器层分为接收反馈层、业务逻辑层；接收反馈层负责与前端对接，接收并且反馈信息，业务逻辑层负责数据处理、内部逻辑实现、与服务器端进行信息交流。内部层间通过传递JavaBean和命令对象进行交流，服务器层与其它层通过socket进行数据的请求和接收。
\\接收反馈层：收到应用层发送的命令后，将信息交给业务逻辑层处理；收到业务逻辑层处理之后的返回后，将数据反馈给应用层。 
\\业务逻辑层：收到接收反馈层的命令和数据后，对数据进行处理加工，并向数据库层发出请求指令；收到数据库的反馈后，对数据进行处理加工，反馈给接收反馈层。 \par
数据库层：\\
数据库层在接收到服务器层的数据请求指令后，通过DAO接口，访问获取或修改数据库的信息，得到反馈后将信息发送给服务器层进行后续处理。通过调用接口，可以不直接访问数据库，一定程度上保证了数据的安全，同时这种低耦合的模块设计使得功能修改和实现更加容易。数据库层和服务器层间通过Socket进行数据的请求和接收。

\subsection{接口设计}
\subsubsection*{应用层}

\begin{tabular}{| l | p{12.5cm} |}%l(left)居左显示 r(right)居右显示 c居中显示
\hline 
序号&描述\\
\hline  
1&public int LogOrReg(String id,String password)\par 应用层在用户登录注册时，与server层进行信息交互与验证,返回int类型参数，对应账号的不同状况\\
\hline 
2&public boolean ChangeState(enum wordlevel,int plan)\par 用户在个人信息中修改词库等级，计划，并更新至server端,返回参数代表是否修改成功\\
\hline
3&public hashmap WordsLearing(String id,enum type,int number=30)\par 用户进行单词学习或复习，从server端获取单词资源,返回值为单词组成的hashmap\\
\hline
4&private boolean changeUserData(String id,String operateType,int number=1)\par 管理员对用户信息进行增删改,返回参数代表是否成功\\
\hline
5&private hashmap queryUserData(String id,String operateType,int number=1)\par 管理员对用户信息进行查寻,返回参数是用户数据的hashmap\\
\hline
6&private boolean changeWordsData(enum wordlevel,String operatetype,int number=0,hashmap newdata=NULL)\par 管理员对词库信息进行增删改,返回参数代表是否成功\\
\hline
\end{tabular}

\subsubsection*{服务器层}
\begin{tabular}{| l | p{12.5cm} |}%l(left)居左显示 r(right)居右显示 c居中显示
\hline 
序号&描述\\
\hline  
1&public User query(final String message)\par 登录注册请求，输入String类型的用户信息，返回符合该拼写的单词信息\\
\hline 
2&public boolean setPlan(final String dictionaryLevel,final int planDays)\par 修改个人学习计划请求，dictionaryLevel词库等级，planDays为计划天数\\
\hline
3&public HashMap<String,Word> queryWords(final String id, final String type, final int amount)\par 请求获取单词，id为用户id，type标记学习或复习，amount为请求获取单词数量，返回HashMap类型\\
\hline
4&public boolean updateUserMessage(final String id,final String type，final String operate)\par 管理员管理用户信息，id为用户id，type为操作类型，operate为操作内容\\
\hline
5&public boolean updateDictionaryWords(final String dictionaryLevel, final String operate, final HashMap<String,Word> words)\par 更新词库信息，dictionaryLevel为词库等级，operate为操作类型，words为新数据\\
\hline
6&public boolean updateDictionaryFiles(File file)\par 管理员上传新词库，file为新词库文件\par 管理员对词库信息进行增删改,返回参数代表是否成功\\
\hline
7&public HashMap<String,Word> queryWord(final String means)\par 用户查询单词，输入指定单词，返回HashMap类型，单词拼写错误的情况下返回NULL\\
\hline
8&public boolean updateUserAuto(final User user)\par 修改用户相关信息，如name，密码，学习进度，修改成功返回true；user为待修改的用户信息类\\
\hline
\end{tabular}

\subsubsection*{数据库层}
\begin{tabular}{| l | p{12.5cm} |}%l(left)居左显示 r(right)居右显示 c居中显示
\hline 
序号&描述\\
\hline  
1&public Word query(final String word)\par 输入String类型的单词拼写，返回符合该拼写的单词信息\\
\hline 
2&public HashMap<String,Word> query(final int from,final int to)\par 批量查询数据库中的单词信息，from和to为所查询单词的起始和结束引索，返回HashMap类型\\
\hline
3&public HashMap<String,Word> queryTrans(final String trans)\par 查询单词翻译包含trans的单词信息，返回HashMap类型\\
\hline
4&public boolean update(final Word word)\par 更新单词word的信息，根据word.getWord()搜索单词并修改其他内容，修改成功返回真反之为假\\
\hline
5&public void addFile(final String file)\par file为文件路径，从文件批量增添数据信息\\
\hline
6&public boolean addData(final String word, final String phone, final String synos)\par 添加单个单词，添加成功返回真反之为假\\
\hline
7&public boolean addData(final Word word)\par 添加单个单词，添加成功返回真反之为假\\
\hline
8&public boolean delData(final Word word)\par 从数据库中删除word，删除成功或不存在返回真反正为假\\
\hline  
9&public boolean delAll(final String table)\par 将名为table的表全部删除，删除成功或不存在返回真反正为假\\
\hline  
10&public User query(final String name)\par 返回名为name的User信息，不存在返回null\\
\hline  
11&public boolean addUser(final User user)\par 添加用户，成功返回真反之为假\\
\hline  
12&public boolean update(final User user, final String name, final String password)\par 将用户user的信息更改，修改成功返回真反之为假\\
\hline  
13&public boolean delUser(final User user)\par 从数据库中删除user，删除成功或不存在返回真反之为假\\
\hline
\end{tabular}
\section{模块设计与实现}
\subsection{数据库设计}
为实现数据模块的独立，存储不同数据时，分别设计了两个数据库：WordDB、PersonDB。同一个数据库下，分为多个表来区分不同数据。
\par WordDB下，不同单词库对应表名：CET4、CET6、TOEFL、IELTS、KaoYan。（可后期增加）\\
其字段说明如下：\\
\begin{tabular}{| l | l | l | l | p{12.5cm} |}%l(left)居左显示 r(right)居右显示 c居中显示
\hline 
字段名&含义&数据类型&备注\\
\hline  
word&单词拼写&varchar(50)&不能为空\\
\hline 
phone&单词读音&varchar(50)&不能为空\\
\hline
synos&单词翻译、词性、对应同义词&Text&不能为空\\
\hline
\end{tabular}
\par PersonDB存放用户信息，其字段说明如下：\\
\begin{tabular}{| l | l | l | l | p{12.5cm} |}%l(left)居左显示 r(right)居右显示 c居中显示
\hline 
字段名&含义&数据类型&备注\\
\hline  
name&用户名&varchar(50)&不能为空，不能重复\\
\hline 
password&用户密码&varchar(50)&不能为空\\
\hline
plan&学习计划&varchar(50)&不能为空，初始为"CET4:0"\\
\hline
speed&学习进度&varchar(50)&不能为空，初始为"CET4:0"\\
\hline
\end{tabular}
\subsection{客户端设计与实现}
\par 客户端总体采用MVC架构，利用Javafx提供的MVC框架。分为界面的FXML和每个界面对应的Controller，还有抽象出来的用户信息，单词信息，词库信息model类。fxml文件为定义组件以及组件位置，大小等信息的文件，不在单独做设计说明，主要说明controller和model部分。
\subsubsection{Controller部分}
首先看总体类图，RootPane负责将不同的模块的界面fxml加载到自己的TabPane中，并将必要的model传送给各个模块controller，使各个模块可以将model与fxml中的组件进行绑定初始化。下面分不同模块进行说明。\\
\includegraphics[scale = 0.43]{Controller类图.png}
\paragraph{登录模块}\quad \\
登录模块在主函数进入时首先加载，controller中含有登录和注册按钮请求时的函数: setLoginButtonAction()和setSignUpButtonAction()。这两个函数获取用户名和密码并调用通信模块向服务器请求登录或者注册服务并显示登陆中或注册中的提示，如果获取不成功，则根据服务器返回的错误信息调用warn()函数弹窗提醒，如果获取成功则初始化UserMessage和WordStockMessage两个model，并向RootPane发出信号，RootPane获取model并开始初始化。
\paragraph{学习复习模块}\quad \\
学习复习模块接收到model后，判断用户是否有计划，如果没有则提示用户新建计划，如果有则用计划初始化SelectWordStock，它将遍历计划中的属性并分别将一个计划与一个ScheduleBox组件进行绑定并展示。当用户点击ScheduleBox中的开始学习按钮或者开始复习按钮，ScheduleBox根据自己的计划属性和是复习还是学习来请求WordsMessage，并初始化LearnPane显示学习界面，学习界面将WordsMessage与组件进行绑定，通过调用WordsMessage中的方法来实现单词的切换与展示。当用户不认识时传递WordsMessage Model给CompleteWordPane使其初始化并绑定model，显示单词完整信息，同时用户可以打开笔记功能，将弹出NotePane并在整个学习过程中都可以进行记笔记。
\paragraph{新建计划模块}\quad \\
该模块接受到UserMessage和WordStockMessage两个model后，利用词库信息初始化NewPlanBox，显示所有词库，同时根据UserMessage判断是否已有计划能否新建。当点击新建计划后，NewPlanBox根据自己的信息（词库名，计划数等）来调用通信模块向服务器发送更新用户信息请求。当请求成功后调用UserMessage中的相关方法，来实现和UserMessage进行绑定的组件的自动更新。
\paragraph{个人信息模块}\quad \\
该模块根据个人信息和词库信息来初始化，显示用户名和已有计划，每个计划对应一个PersonalScheduleBox。PersonalScheduleBox中可以修改和删除该计划，当修改删除按钮被按下后，发送更新计划的申请。成功后则调用UserMessage中的相应方法更新model。
\paragraph{查询单词模块}\quad \\
查询单词被加载后，用户可以输入单词进行查询，查询按钮监听输入框改变，没有输入时不能查询。按下按钮后则调用通信模块，向服务器请求服务，根据返回信息来展示单词，如果未收录或单词拼错则提示，如果网络异常则弹窗提醒。
\subsubsection{Model部分}
\includegraphics[scale = 0.3]{Model.png}
User和Word为服务器端封装好服务器信息后的类，model只是提取其中的信息。其中UserMessage含有ObservableMap可以和组件进行绑定，同时包含了添加计划修改计划，删除计划等方法。WordStockMessage含有词库信息，包含所有词库的名称和总次数，由于用户没有权限管理词库，故不提供修改的方法。WordsMessage中存放一批从服务器请求来的Word类，其中包含WordProperty类，此类可以和用户界面进行绑定，达到实时更新的功能，同时此类还将Word中的信息加工处理成为展示时的格式。WordsMessage中含有NextWord()方法，当调用时取下一个Word更新WordProperty，使界面也可同时更新。
\subsubsection{通信模块部分}
\includegraphics[scale = 0.25]{通信模块类图.png}
通信模块负责client端和server端的信息交互。
\paragraph{父类sendString} \quad \\
\quad 1.继承task类，可作为线程task执行\\
\quad 2.定义了serverip，端口号，\\
\quad 3.初始化发送地址\\
\paragraph{继承子父类的子类} \quad \\
\quad 1.sendRegister: 发送注册信息，并通过getMymesssage()得到返回信息\\
\quad 2.sendLogin: 发送登录信息，并通过getMymessage()将接收到的信息重封装返回\\
\quad 3.sendChangePlan: 发送修改计划的信息，并通过getMymessage()获取返回值\\
\quad 4.sendAskForWord: 发送请求单词信息，通过getMymessage()封装信息继而返回\\
\quad 5.sendQueryWord: 发送查询单词信息，通过getMymessage()获取返回值\\
\quad 6.sendAskWordStockMessage: 发送查询词库信息，通过getMymessage()获取返回值\\
\subsection{服务器设计与实现}
\paragraph{功能层}\quad \\
\paragraph{类图设计}\quad \\
本模块的类图主要是接收应用层的数据、进行逻辑处理，并与数据库层进行交互
\includegraphics[scale = 0.35]{server.png}\\
(1)myServer:利用socket，负责接收前端传送的命令，交给Handler类处理\\
(2)Handler：继承了Thread类，使用多线程，并行地处理前端命令\\
(3)toDB：连接数据库的类，负责处理前端信息并且向数据库层发送指令\\
\paragraph{数据库层}\quad \\
\paragraph{类图设计}\quad \\
本模块的类图主要是数据库的操作类图。\\
\includegraphics[scale = 0.35]{DB.png}\\
类的定义如下：\\
（1）DB；抽象类，负责提供相应的公共接口\\
（2）UserDB：用户类，继承DB类，负责用户信息的增删查改\\
（3）Word DB：单词类，继承DB类，负责词库信息的增删查改\\
\section{系统测试}
\subsection{注册}
在用户名，密码框分别输入用户名，密码，点击注册按钮，进行注册操作。\\
\includegraphics[scale = 0.8]{注册.png}\\
成功后弹窗提醒\\
\includegraphics[scale = 0.8]{注册成功.png}\\
失败则提示用户\\
\includegraphics[scale = 0.7]{注册失败.png}\\
\subsection{登录}
在用户名，密码框分别输入用户名，密码，点击登录按钮，进行登录操作。\\
\includegraphics[scale = 0.7]{注册.png}\\
登录成功后：\\
\includegraphics[scale = 0.5]{主界面.jpg}\\
出现主界面，四大功能模块。
\subsection{查询单词}
在单词输入框输入单词，点击查询按钮，进行单词查询操作。查询成功，下方出现单词的信息(包括拼写，音标，含义，同近义词)\\
\includegraphics[scale = 0.5]{查询单词.jpg}\\
\subsection{新建计划}
\includegraphics[scale = 0.5]{新建计划.jpg}\\
选择词库，设置个人计划，点击新建按钮
\subsection{个人信息（含计划修改删除）}
\includegraphics[scale = 0.6]{个人信息.jpg}\\
个人信息栏包括用户名，个人学习计划等。在此处进行个人学习计划修改，选择个人每日计划，点击确定修改即可\\
\subsection{学习单词}
开始学习模块，包括个人学习计划等信息，点击开始学习按钮进入单词学习\\
\includegraphics[scale = 0.6]{开始学习1.jpg}\\
单词学习可选择“认识”，“不认识”，“退出”\\
\includegraphics[scale = 0.6]{开始学习2.jpg}\\
“认识”：跳转至下一个单词学习\\
“不认识”：显示单词的信息，并可进行笔记记录\\
“退出”：保存进度，退出当前学习\\
\subsection{笔记记录}
\includegraphics[scale = 0.43]{笔记.jpg}\\
在学习中选择“不认识”后，会显示单词信息，并可选择进行笔记记录
笔记本可保存到本地，也可从本地导入已有的笔记本。
\section{小结}
本次IBBB单词学习系统的开发中，我们小组利用github、腾讯会议等工具进行线上团队开发。开发过程中，我们分工明确，各尽其力。从需求的提出、架构的建设到最后的整合测试，我们都十分认真地对待。线上的开发，虽然不利于交流，但是却让我们的开发习惯大大提升，比如：参数变量命名规范、给代码写注释。短短一个月内，我们体验了一次敏捷开发，训练出了在短时间内做出决定、修改需求、编写代码的能力。
这次开发的顺利完成，也让我们将课堂上所学的知识用到了实践中来。Java语言的编程、数据库的访问操作、软件工程基本原则、以及软件体系架构设计。我们深深地体会到在开发的过程中，遵从软件开发的原则是多么的重要。依赖倒置原则、里氏替换原则、接口分离原则，这些在上学期还是存在于“无聊”的软件工程导论课上的纸上谈兵一般的知识，现在却体现在了我们的系统中。
而对于体系架构的设计，则是我们这一次开发的重点关注目标。我们深知：架构的好坏，影响着整个系统的各方面性能：安全性、可维护性、可扩充性等等。纸上得来终觉浅，绝知此事要躬行。如何去设计一个好的架构，并且将之体现在系统的设计中，成了我们这次实验的首要目标。因此在这一次的设计中，我们并没有把软件的功能是否强大放在首位，而是更侧重于软件架构的设计。开发过程中，我们大胆尝试，将所学的知识用于实践之中，先后设计了两层CS风格、三层CS风格、分层风格、管道过滤器风格、事件驱动风格等多种架构风格，最后经过讨论并结合项目的实际情况，我们选择了三层CS架构风格作为主体，采用应用层—功能层—数据库层的设计，并且在局部实现了事件驱动风格和管道过滤器风格。通过这一次的开发，我们对于架构风格有了更深层次的了解，也提前接触了多人开发模式，对于团队开发这个概念有了一定的了解，这对于我们以后的学习和工作都会起到相当大的帮助。
\section{附录}
解析json并导出到数据库Python脚本\\
{\setmainfont{Courier New Bold}                          % 设置代码字体                   
\begin{lstlisting}
import json
with open('5.txt', 'w', encoding='utf-8') as txt:
    with open('WordsData/TOEFL.json', 'r',\
              encoding='utf-8') as f:
        data = json.load(f)
        for j in range(len(data)):
            word = data[j]['headWord']
            phone = ''
            if 'usphone' in \ 
            data[j]['content']['word']['content']:
                phone = '[US]' + \ 
                        data[j]['content']['word'] \ 
                        ['content']['usphone']
            if 'ukphone' in \ 
            data[j]['content']['word']['content']:
                if phone is not '':
                    phone = phone + '\n'
                phone = phone + '[UK]'+ \ 
                        data[j]['content'] \ 
                        ['word']['content']['ukphone']
            string = word + '\n-\n' +phone +'\n--\n'
            if 'syno' in \ 
            data[j]['content']['word']['content']:
                syno = data[j]['content']['word']\ 
                           ['content']['syno']['synos']
                for x in syno:
                    string = string + \ 
                             x['pos']+'\n'+x['tran']+'\n' \
                             +(','.join(str(i['w']) \ 
                             for i in x['hwds'])) + '\n'
            elif 'trans' in data[j]['content']\ 
                                ['word']['content']:
                for x in data[j]['content']['word']\
                             ['content']['trans']:
                    if 'pos' in x:
                        string = string + x['pos']+'\n'
                    if 'tranCn' in x:
                        string = string + x['tranCn']+'\n'
            txt.write(string+"---\n")
\end{lstlisting}}
\newpage
\bibliographystyle{plain}
\bibliography{biblist}
\end{document}
